package com.yihaodian.cluster;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;

/**
 * (Virtual) Group of nodes
 * 
 * @author zhouhang
 * 
 */
public class Cluster {

	private static Logger log = Logger.getLogger(Cluster.class);

	private final String id;
	private final ImmutableMap<String, Node> nodes;
	private final String masterId;

	public Cluster(String id, String masterNodeId,
			ImmutableMap<String, Node> nodes) {
		this.id = id;
		this.masterId = masterNodeId;
		this.nodes = nodes;
	}

	/**
	 * Get cluster id/name
	 * 
	 * @return
	 */
	public String getId() {
		return id;
	}

	/**
	 * Get node
	 */
	public Node getNode(String id) {
		Node node = null;
		if (nodes != null) {
			node = nodes.get(id);
		}
		return node;
	}

	/**
	 * Get all nodes
	 * 
	 * @return
	 */
	public Collection<Node> getNodes() {
		return nodes.values();
	}

	/**
	 * Get master node
	 * 
	 * @return
	 */
	public Node getMaster() {
		return nodes.get(masterId);
	}

	@Override
	public String toString() {
		return "Cluster [id=" + id + ", nodes=" + nodes + ", masterId="
				+ masterId + "]";
	}

	public static class Builder {
		private String id;
		private Map<String, Node> nodes= new HashMap<String, Node>();
		private String masterId;

		public Builder() {
			this.id = "";
			this.masterId = "";
			this.nodes = Maps.newHashMap();
		}

		public Builder(Cluster cluster) {
			this.id = cluster.id;

			if (cluster.nodes == null)
				this.nodes = Maps.newHashMap();
			else
				this.nodes = new HashMap<String, Node>(cluster.nodes);

			this.masterId = cluster.masterId;
		}

		public Builder setId(String id) {
			this.id = id;

			return this;
		}

		public Builder setMaster(Node master) {
			masterId = master.getId();

			return this;
		}

		/**
		 * Add node
		 */
		public Builder addNode(Node node) {
			nodes.put(node.getId(), node);

			return this;
		}

		/**
		 * Remove node
		 */
		public Builder removeNode(Node node) {
			nodes.remove(node.getId());

			return this;
		}
		
		public boolean contains(String id)
		{
			return nodes.containsKey(id);
		}

		public Cluster build() {
			if(nodes==null)nodes=new HashMap<String, Node>();
			return new Cluster(id, masterId,
					new ImmutableMap.Builder<String, Node>().putAll(nodes)
							.build());
		}
	}
}
